// 服务端入口，只在服务器运行
import { createApp, asyncDataFilter } from "./main";
import { renderToString } from "vue/server-renderer";

export async function render(url: string, manifest: any) {
  const { app, router, store } = createApp();
  // 同构渲染的关键 复用router的配置
  await router.push(url);
  // 等待解析完异步组件
  await router.isReady();

  const matchedComponents = router.currentRoute.value.matched.flatMap(record =>
    Object.values(record.components)
  );
  // console.log("matchedComponents", matchedComponents);
  // 对所有匹配的路由组件调用 `asyncData()`
  // await asyncDataFilter(matchedComponents, store, router.currentRoute);
  // const context: any = {};
  // const appHtml = await renderToString(app, context);
  // const state = store.state;
  // if (import.meta.env.PROD) {
  //   const preloadLinks = renderLinks(context.modules, manifest);
  //   return { appHtml, state, preloadLinks };
  // } else {
  //   return { appHtml, state };
  // }
  await asyncDataFilter(matchedComponents, store, router.currentRoute);

  const context: any = {};
  // renderToString 返回的是一个Promise
  const appHtml = await renderToString(app, context);
  const state = store.state;
  if (import.meta.env.PROD) {
    // 清单文件ID的集合
    const preloadLinks = renderLinks(context.modules, manifest);
    // 当生产环境的时候 暴露出去preloadLinks
    return {
      appHtml,
      state,
      preloadLinks
    };
  } else {
    // 开发环境
    return {
      appHtml,
      state
    };
  }
}

/**
 * 第一个参数 清单文件ID的集合
 * 第二个参数 清单文件 JSON对象
 * */
function renderLinks(modules: any, manifest: any) {
  let links = "";
  modules.forEach((id :any) => {
    const files = manifest[id];
    if (files) {
      files.forEach((file: any) => {
        // 拿到文件的路径
        links += renderPreloadLink(file);
      });
    }
  });
  return links;
}

// 处理file 根据不同的后缀名 进行不同的引入方式
function renderPreloadLink(file: any) {
  if (file.endsWith(".js")) {
    return `<link rel="modulepreload" crossorigin href="${file}">`;
  } else if (file.endsWith(".css")) {
    return `<link rel="stylesheet" href="${file}">`;
  } else if (file.endsWith(".woff")) {
    return ` <link rel="preload" href="${file}" as="font" type="font/woff" crossorigin>`;
  } else if (file.endsWith(".woff2")) {
    return ` <link rel="preload" href="${file}" as="font" type="font/woff2" crossorigin>`;
  } else if (file.endsWith(".gif")) {
    return ` <link rel="preload" href="${file}" as="image" type="image/gif">`;
  } else if (file.endsWith(".jpg") || file.endsWith(".jpeg")) {
    return ` <link rel="preload" href="${file}" as="image" type="image/jpeg">`;
  } else if (file.endsWith(".png")) {
    return ` <link rel="preload" href="${file}" as="image" type="image/png">`;
  } else {
    // TODO
    return "";
  }
}
